const express = require('express');
const xss = require('xss');
const router = express.Router();
const Joi = require('joi');
const bcrypt = require('bcrypt');
const moment = require('moment');
const jwt = require('jsonwebtoken');
const auth = require('../middleware/auth');
const admin = require('../middleware/admin');

router.get('/me',auth, async (req,res)=>{
    try{
        const db = req.app.get('db');
        let user = await db.get('Select id,nickname,phoneNumber,isAdmin,createDateTime from users where id=? AND isDisabled=0',req.user.id);
        return res.send({'user':user});
    }catch(err){
        return res.status(500).send({'message':err.message});
    }
});

router.get('/',[auth,admin], async (req,res)=>{
    try{
        const db = req.app.get('db');
        let users = await db.all('Select id,nickname,phoneNumber,isAdmin,createDateTime from users where isDisabled=0');
        return res.send({'users':users});
    }catch(err){
        return res.status(500).send({'message':err.message});
    }
});

router.post('/', async (req,res) =>{
    try{
        const {error} = validateUser(req.body);
        if(error){
            return res.status(400).send({'message':error.details[0].message});
        }
        const db = req.app.get('db');
        let user = await db.get('Select * from users where phoneNumber=? And IsDisabled=0',req.body.phone);
        if (user) return res.status(400).send({'message':'Phone Number already been used.'});
    
        const salt = await bcrypt.genSalt(10);
        const hashedPassword = await bcrypt.hash(req.body.password,salt);
        
        user = await db.get('Select * from users where phoneNumber=? And IsDisabled=1',req.body.phone);

        if (user){
            await db.run('UPDATE users SET nickname=? ,password=?,createDateTime=?,isDisabled=0,isAdmin=0 WHERE phoneNumber=?',
            xss(req.body.nickname),
            hashedPassword,
            moment().format('yyyy-MM-DD HH:mm:ss'),
            xss(req.body.phone));
        }else{
            await db.run('INSERT INTO users (nickname,phoneNumber,password,createDateTime) VALUES (?,?,?,?)',
            xss(req.body.nickname),
            xss(req.body.phone),
            hashedPassword,
            moment().format('yyyy-MM-DD HH:mm:ss'));
        }
        user = await db.get('Select id,nickname,phoneNumber,isAdmin,createDateTime from users where phoneNumber=?',
            req.body.phone);
        const token = jwt.sign({id:user.id, nickname:user.nickname, isAdmin:user.isAdmin},'jwtToken');
        res.header('x-auth-token',token).status(201).send({'user':user,'message':'new user has created'});
    }catch(err){
        return res.status(500).send({'message':err.message});
    }
});

router.delete('/:id',[auth,admin],async (req,res)=>{
    try {
        const db = req.app.get('db');
        const result = await isExistingUser(req,res);
        if (!result) return;
        if (result.id == req.user.id)
            return res.status(400).send({'message':'cannot delete yourself'});
        await db.run('UPDATE users SET isDisabled=? WHERE id=?',1,
            parseInt(req.params.id));
        const user = await db.get('Select id,nickname,phoneNumber,isAdmin,createDateTime from users Where isDisabled = 1 AND id=?;', 
            parseInt(req.params.id));
        res.send({'user':user,'message':'user deleted'});
    } catch (err) {
        return res.status(500).send({'message':err.message});
    }
});

function validateUser(user){
    const schema = Joi.object({
        nickname : Joi.string()
            .min(3)
            .max(20)
            .required(),
        phone:Joi.string()
            .regex(new RegExp('^[1][3,4,5,7,8][0-9]{9}$'))
            .required()
            .error(new Joi.ValidationError('Invaild Phone Number',
                [{message:'Phone Number is illegal'}])),
        password: Joi.string()
            .regex(new RegExp('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$'))
            .required()
            .error(new Joi.ValidationError('Invaild Password',
                [{message:'Password must at least 8 characters, at least 1 special character,1 number and 1 upper case character'}]))
    });
    return schema.validate(user);
}

async function isExistingUser(req,res){
    const db = req.app.get('db');
    let car = await db.get('Select * from users Where isDisabled = 0 AND id=?;',
        req.params.id);
    if (!car) {
        res.status(404).send({'message':'cannot find the user with the id'});
        return false;
    }
    return car;
}

module.exports = router;


